package flyln.uestc.edu.a2048;

import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.GridLayout;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by asus on 2017/8/27.
 */

public class GameView extends GridLayout {

    String TAG  = "game2048";
    public  static double  OFFSET_THRESHOLD = 100;

    private AnimLayer animLayer = new AnimLayer(getContext());
    private Card[][] cards = new Card[4][4];
    private List<Point> emptyPoints = new ArrayList<Point>();
    GameListener listener = null;


    public GameView(Context context) {
        super(context);

        initGameView();
    }

    private void initGameView() {

        setColumnCount(4);

        setOnTouchListener(new OnTouchListener() {

            private float startX,startY,offsetX,offsetY;
            private boolean moved = false;
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) {

                    //手指按下，记录按下的位置P1(startX,startY)
                    case MotionEvent.ACTION_DOWN:
                        startX = event.getX();
                        startY = event.getY();
                        break;
                    case MotionEvent.ACTION_UP:
                        moved = false;
                        offsetX = event.getX() - startX;
                        offsetY = event.getY() - startY;

                        if (Math.abs(offsetX) > Math.abs(offsetY) ){
                            if (offsetX > OFFSET_THRESHOLD){
                                moveRight();
                                moved = true;
                            }
                            else if (offsetX < -OFFSET_THRESHOLD){
                                moveLeft();
                                moved = true;
                            }
                        }
                        if (Math.abs(offsetX) < Math.abs(offsetY) ){
                            if (offsetY > OFFSET_THRESHOLD){
                                moveDown();
                                moved = true;
                            }

                            else if (offsetY < -OFFSET_THRESHOLD){
                                moveUp();
                                moved = true;
                            }

                        }
                        if (moved){
                            generateRandomCard();
                        }


                        break;


                }

                return true;
            }
        });
    }

    private void moveUp() {
        Log.d(TAG,"moveUp");
        for (int j=0 ; j<4 ; j++) {
            List<Integer> list = new ArrayList<>();
            for (int i = 0; i < 4; i++) {
                if (cards[i][j].getNum() > 0){
                    list.add(cards[i][j].getNum());
                }
            }
            //赋值一行(列)
            Integer[] nums = mergeOneLine(list);
            for (int k = 0 ; k < 4; k++){
                cards[k][j].setNum(nums[k]);
            }
        }
    }
    private void moveDown() {
        Log.d(TAG,"moveDown");
        for (int j=0 ; j<4 ; j++) {
            List<Integer> list = new ArrayList<>();
            for (int i = 3 ; i >= 0  ; i--) {
                if (cards[i][j].getNum() > 0){
                    list.add(cards[i][j].getNum());
                }
            }
            //赋值一行(列)
            Integer[] nums = mergeOneLine(list);
            for (int k = 0 ; k < 4 ; k++){
                cards[3-k][j].setNum(nums[k]);
            }
        }
    }
    private void moveLeft() {

        Log.d(TAG,"moveLeft");

        for (int i=0 ; i<4 ; i++) {
            List<Integer> list = new ArrayList<>();
            for (int j = 0; j < 4; j++) {
                if (cards[i][j].getNum() > 0){
                    list.add(cards[i][j].getNum());
                }
            }
            //赋值一行(列)
            Integer[] nums = mergeOneLine(list);
            for (int k = 0 ; k < 4; k++){
                cards[i][k].setNum(nums[k]);
            }
        }

    }
    private void moveRight() {
        Log.d(TAG,"moveRight");
        for (int i=0 ; i<4 ; i++) {
            List<Integer> list = new ArrayList<>();
            for (int j = 3; j >= 0; j--) {
                if (cards[i][j].getNum() > 0){
                    list.add(cards[i][j].getNum());
                }
            }
            //赋值一行(列)
            Integer[] nums = mergeOneLine(list);
            for (int k = 0 ; k < 4 ; k++){
                cards[i][3-k].setNum(nums[k]);
            }
        }

    }

    private Integer[] mergeOneLine(List<Integer> list) {

        Integer[] nums = new Integer[4];



        for (int i =0; i< list.size() - 1 ; i++){
            //相邻卡片数字相同
            if ( list.get(i)  == list.get(i+1)  && list.get(i) > 0){

                //当前数字翻倍
                list.set(i ,list.get(i)*2);
                //通知加分
                if (listener != null)
                    listener.addScore(list.get(i).intValue());
                //后面数字前移
                for (int j = i+1;j<list.size()-1;j++){
                    list.set(j,list.get(j+1));
                }
                //因为有合并，所以删除最后一个元素  2 2 -> 4
                list.remove(list.size()-1);
            }
        }

        for (int i =0 ; i< list.size(); i++){
            nums[i] = list.get(i);
        }
        for (int j = list.size() ; j < 4 ; j++){
            nums[j] = 0;
        }


        return nums;

    }


    public void setListener(GameListener listener) {
        this.listener = listener;
    }

    public GameView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initGameView();
    }

    public GameView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initGameView();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        int cardSize = ( Math.min(w,h) -10 ) / 4;
        addCards(cardSize);

        //记录卡片尺寸
        Config.CARD_HEIGHT = cardSize;
        Config.CARD_WIDTH = cardSize;

        generateRandomCard();
        generateRandomCard();
    }

    private void addCards(int cardSize) {
        Card card;
        for (int i=0 ; i< 4 ;i++)
            for (int j=0; j<4;j++){
                card = new Card(getContext());
                card.setNum(0);
                addView(card,cardSize,cardSize);
                cards[i][j] = card;
            }
    }
    public void generateRandomCard(){
        emptyPoints.clear();//清空空点

        //更新空点
        for (int i = 0 ; i < 4 ;i ++){
            for (int j = 0 ; j < 4 ; j++){
                if (cards[i][j].getNum() == 0){
                    emptyPoints.add(new Point(i,j));
                }
            }
        }

        int newIndex = (int)(Math.random()*emptyPoints.size());
        Point newPoint = emptyPoints.remove(newIndex);
        cards[newPoint.x][newPoint.y].setNum(Math.random() > 0.9 ? 4 : 2) ;
        animLayer.createScaleTo1(cards[newPoint.x][newPoint.y]);
    }





    public interface GameListener {
        void addScore(int score);
        void updateBest(int score);

    }
}
